// Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms
//    Pseudocode from article of the above name in PODC96 (with two typos corrected), by Maged M. Michael and Michael L. Scott. Corrected version also appeared in JPDC, 1998. 
//
//    The non-blocking concurrent queue algorithm performs well on dedicated as well as multiprogrammed multiprocessors with and without contention. The algorithm requires a universal atomic primitive, CAS or LL/SC. 
//
//    The two-lock concurrent queue algorithm performs well on dedicated multiprocessors under high contention. Useful for multiprocessors without a universal atomic primitive. 
//
//    --------------------------------------------------------------------------------
//
//    Two-Lock Concurrent Queue Algorithm
//    structure node_t {value: data type, next: pointer to node_t}
//    structure queue_t {Head: pointer to node_t, Tail: pointer to node_t,
//          H_lock: lock type, T_lock: lock type}
//
//  initialize(Q: pointer to queue_t)
//    node = new_node()		// Allocate a free node
//    node->next = NULL          // Make it the only node in the linked list
//    Q->Head = Q->Tail = node	// Both Head and Tail point to it
//    Q->H_lock = Q->T_lock = FREE	// Locks are initially free
//
//    enqueue(Q: pointer to queue_t, value: data type)
//    node = new_node()	        // Allocate a new node from the free list
//    node->value = value		// Copy enqueued value into node
//    node->next = NULL          // Set next pointer of node to NULL
//    lock(&Q->T_lock)		// Acquire T_lock in order to access Tail
//    Q->Tail->next = node	// Link node at the end of the linked list
//    Q->Tail = node		// Swing Tail to node
//    unlock(&Q->T_lock)		// Release T_lock
//
//    dequeue(Q: pointer to queue_t, pvalue: pointer to data type): boolean
//          lock(&Q->H_lock)	        // Acquire H_lock in order to access Head
//          node = Q->Head		// Read Head
//          new_head = node->next	// Read next pointer
//          if new_head == NULL	// Is queue empty?
//          unlock(&Q->H_lock)	// Release H_lock before return
//          return FALSE		// Queue was empty
//          endif
//          *pvalue = new_head->value	// Queue not empty.  Read value before release
//          Q->Head = new_head	// Swing Head to next node
//          unlock(&Q->H_lock)		// Release H_lock
//          free(node)			// Free node
//          return} TRUE		// Queue was not empty, dequeue succeeded

#pragma once
//CM pthread_mutex_t

HANDLE g_hHeaderMutex;// = CreateMutex(NULL, FALSE, _T("Mutex_Only_One_Instance_Allowed"));
HANDLE g_hTailerMutex;// = CreateMutex(NULL, FALSE, _T("Mutex_Only_One_Instance_Allowed"));

template< typename K, typename V >
struct Maillon {
	K clef;
	V valeur;
	Maillon *succ;
};

template <typename T>
struct SLinkNode_T /*<T>*/ {
	T TValue;
	SLinkNode_T* next;

	SLinkNode_T() {
		next.node = NULL;
		next.count = 0;
	}

	SLinkNode_T(SLinkNode_T next, T value) {
		this->next = next;
		this->TValue = value;
	}
};

template <typename T>
struct SQueue_T {
	SLinkNode_T* Head;
	SLinkNode_T* Tail;//: pointer to node_t,
	HANDLE pthread_mutex__H_lock;//: lock type;
	HANDLE pthread_mutex__T_lock;//: lock type
};

class CTLCQA
{
public:
    CTLCQA(void);
    ~CTLCQA(void);
};

